# coding: utf8
import urllib

import tornado
from tornado import gen
from tornado.escape import json_decode

import cms_config
from app.base_controller import BaseController
from app.common import global_space, wzhifuSDK
from app.models import VideoType, PriceType, VideoTime, PriceTypeDetail, VideoOrder, VideoOrderState
from libs.util import check_param
import logging as log
import uuid
import hashlib
import urllib.request

log.basicConfig(format='[%(asctime)s] [%(filename)s]:[line:%(lineno)d] [%(levelname)s] %(message)s', level=log.INFO)


# /api/video-type
class VideoTypeList(BaseController):

    @gen.coroutine
    def get(self):
        data = []
        for videoType in VideoType.objects.filter(state=0).order_by('show_order').all():
            data.append(videoType.to_dict())
        self.render_json(data=data)


# /api/video-time
class VideoTimeList(BaseController):

    @gen.coroutine
    def get(self):
        data = []
        for videoType in VideoTime.objects.filter(state=0).order_by('show_order').all():
            data.append(videoType.to_dict())
        self.render_json(data=data)


# /api/video-price
class VideoPrice(BaseController):
    @gen.coroutine
    def get(self):
        type = self.get_argument("videoType")
        param = [type, ]
        if check_param(param):
            self.render_json(code=1001, msg='参数丢失')
            return

        data = []
        for videoType in VideoType.objects.filter(state=0).filter(id=type).first().price_type.all():
            data.append(videoType.to_dict())
        self.render_json(data=data)


# /video-order-modify
class VideoOrderModify(BaseController):
    @gen.coroutine
    def post(self):
        id = self.get_json_argument("id", '')
        video_type = self.get_json_argument("video-type", '')
        video_time = self.get_json_argument("video-time", '')
        video_price = self.get_json_argument("video-price", [])
        requirement = self.get_json_argument("requirement", '')
        contacts = self.get_json_argument("contacts", '')
        phone = self.get_json_argument("phone", '')
        city = self.get_json_argument("city", '')
        second_city = self.get_json_argument("second_city", '')
        session_id = self.get_json_argument("session_id", '')

        param = [id, video_type, video_time, video_price, requirement, contacts, phone, city, session_id]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
            return
        session = global_space.very_session(session_id)
        if not session:
            self.render_json(code=999, msg='session 失效')
            return

        openid = session['openid']

        v_type = VideoType.objects.filter().filter(id=video_type).prefetch_related('price_type').first()
        v_ptd = [key for key in PriceTypeDetail.objects.filter(id__in=video_price).all()]

        vtime = VideoTime.objects.filter(id=video_time).first()

        if not v_type or not vtime or len(v_ptd) != len(video_price):
            self.render_json(code=1002, msg='参数不正确')
            return
        price = 0
        for key in v_ptd:
            # log.info(key.price_type_detail_set.first().to_dict)
            price += key.transaction_price

        vo = VideoOrder.objects.filter(id=id).first()
        if not vo:
            self.render_json(code=1008, msg='订单不存在')
            return
        if vo.state.id != 1:
            self.render_json(code=1004, msg='此状态不允许修改')
            return
        vo.city = city
        vo.second_city = second_city
        vo.video_type = v_type
        vo.video_time = vtime
        vo.requirement = requirement
        vo.contacts = contacts
        vo.phone = phone
        vo.openid = openid

        vo.price = price
        vo.price_type_detail.set(v_ptd)
        vo.save()
        self.render_json(data=vo.get_id())


class PayNotify(BaseController):
    def post(self):
        log.info(json_decode(self.request.body))

    def get(self):
        log.info(json_decode(self.request.body))


class Pay(BaseController):
    @tornado.web.asynchronous
    def post(self):
        url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
        http = tornado.httpclient.AsyncHTTPClient()
        id = self.get_json_argument("id", '')
        remote_ip = self.request.remote_ip
        param = [id, ]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
            return
        vo = VideoOrder.objects.filter(id=id).first()

        if not vo:
            self.render_json(code=1008, msg='订单不存在')
            return
        if vo.state.id != 1:
            self.render_json(code=1004, msg='此状态不允许付款')
            return

        data = {"appid": cms_config.app_id,
                "mch_id": cms_config.mch_id,
                "nonce_str": uuid.uuid1().hex,
                "body": "欢玺视频定制",
                "out_trade_no": str(vo.order_id),
                "total_fee": str(vo.price * 100),
                "spbill_create_ip": remote_ip,
                "notify_url": "https://api.joyfulmedia.cn/api/video-order-notify",
                "trade_type": "JSAPI"
                }
        data = sorted(data.items(), key=lambda d: d[0], reverse=False)
        send_date = {}
        temp_string = ""
        for k, v in data:
            send_date[k] = v
            temp_string = temp_string + k + "=" + v + "&"
        temp_string = temp_string + "key=" + cms_config.security_key
        sign = hashlib.md5(temp_string.encode("utf-8")).hexdigest().upper()
        send_date['sign'] = sign
        log.info(wzhifuSDK.trans_dict_to_xml(send_date))
        http.fetch(url, method='POST', body=wzhifuSDK.trans_dict_to_xml(send_date),
                   callback=self.on_response)

    def on_response(self, response):
        if response.error:
            self.render_json(code=1002, msg='系统异常')
        else:
            # json = tornado.escape.json_decode(response.body)
            log.info(response)
            log.info(response.body.decode('utf-8'))
            # log.info(wzhifuSDK.trans_xml_to_dict(response.body.decode('utf-8')))
            self.render_json(data={})


# /video-order-create
class VideoOrderCreate(BaseController):
    @gen.coroutine
    def post(self):
        video_type = self.get_json_argument("video-type", '')
        video_time = self.get_json_argument("video-time", '')
        video_price = self.get_json_argument("video-price", [])
        requirement = self.get_json_argument("requirement", '')
        contacts = self.get_json_argument("contacts", '')
        phone = self.get_json_argument("phone", '')
        city = self.get_json_argument("city", '')
        second_city = self.get_json_argument("second_city", '')
        session_id = self.get_json_argument("session_id", '')

        param = [video_type, video_time, video_price, contacts, phone, city, session_id]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
            return
        session = global_space.very_session(session_id)
        if not session:
            self.render_json(code=999, msg='session 失效')
            return

        openid = session['openid']
        v_type = VideoType.objects.filter().filter(id=video_type).first()

        v_ptd = [key for key in PriceTypeDetail.objects.filter(id__in=video_price).all()]

        vtime = VideoTime.objects.filter(id=video_time).first()
        # VideoOrderStats.ob
        if not v_type or not vtime or len(v_ptd) != len(video_price):
            self.render_json(code=1002, msg='参数不正确')
            return
        price = 0
        for key in v_ptd:
            price += key.transaction_price
        order_id = uuid.uuid1().hex
        state = VideoOrderState.objects.filter(id=1).first()
        vo = VideoOrder.objects.create(state=state, city=city, second_city=second_city, video_type=v_type, video_time=vtime, requirement=requirement,
                                       contacts=contacts, phone=phone, openid=openid, price=price, pay_amount=0, back_amount=0, order_id=order_id)
        vo.price_type_detail.set(v_ptd)

        self.render_json(data=vo.get_id())


# /api/video-order-detail
class VideoOrderDetail(BaseController):
    @gen.coroutine
    def get(self):
        id = self.get_argument("id", '')
        param = [id]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
            return
        vo = VideoOrder.objects.filter(id=id).select_related('video_type'). \
            select_related('video_time').prefetch_related('price_type_detail').first()
        if not vo:
            self.render_json(code=1002, msg='订单不存在')
            return

        self.render_json(data=vo.to_dict(1))
